package cn.yhjz.generator.util;

import cn.yhjz.generator.entity.SysGenModelProp;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlCreateTableParser;
import lombok.extern.slf4j.Slf4j;

import java.sql.JDBCType;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 解析create语句
 *
 * @author maguoping
 */
@Slf4j
public class SqlUtil {
    private static Pattern linePattern = Pattern.compile("_(\\w)");
    private static Pattern humpPattern = Pattern.compile("[A-Z]");

    public static Map<String, Object> r(String sql) {
        Map<String, Object> resultMap = new HashMap<>();
        MySqlCreateTableParser parser = new MySqlCreateTableParser(sql);
        SQLStatement statement = parser.parseStatement();
        SQLCreateTableStatement createTableStatement = (SQLCreateTableStatement) statement;
        String tableName = createTableStatement.getTableName();
        tableName = tableName.replaceAll("`", "");
        log.info("表名:" + tableName);
        List<String> columnNameList = createTableStatement.getColumnNames(true);
        List<SysGenModelProp> propList = new ArrayList<>();
        for (String columnName : columnNameList) {
            if (columnName.equals("discription")) {
                log.info("haha");
            }
            SQLColumnDefinition sqlColumnDefinition = createTableStatement.getColumn(columnName);
            String dataType = sqlColumnDefinition.getDataType().getName();
            JDBCType sqlDataType = JDBCType.valueOf(sqlColumnDefinition.jdbcType());
            String propType = null;
            SysGenModelProp prop = new SysGenModelProp();
            boolean isPrimaryKey = sqlColumnDefinition.isPrimaryKey();
            if (isPrimaryKey) {
                prop.setIsPk("1");
            }
            if (JDBCType.BIGINT == sqlDataType
                    || JDBCType.INTEGER == sqlDataType) {
                propType = "Long";
            }
            if (JDBCType.VARCHAR == sqlDataType
                    || JDBCType.CHAR == sqlDataType
                    || JDBCType.NVARCHAR == sqlDataType
                    || JDBCType.LONGNVARCHAR == sqlDataType
                    || JDBCType.LONGVARCHAR == sqlDataType
                    || "longtext".equalsIgnoreCase(dataType)
                    || "text".equalsIgnoreCase(dataType)
            ) {
                propType = "String";
            }
            if (JDBCType.TINYINT == sqlDataType
                    || JDBCType.SMALLINT == sqlDataType) {
                propType = "Integer";
            }
            if (JDBCType.DATE == sqlDataType
                    || JDBCType.TIMESTAMP == sqlDataType
            ) {
                propType = "Date";
            }
            if (JDBCType.DOUBLE == sqlDataType
            ) {
                propType = "Double";
            }
            SQLCharExpr comment = (SQLCharExpr) sqlColumnDefinition.getComment();
            if (comment != null) {
                String commentString = comment.getText();
                prop.setColumnComment(commentString);
            }
            prop.setCreatedTime(new Date());
            prop.setColumnName(columnName);
            prop.setColumnType(dataType.toUpperCase());
            prop.setJavaType(propType);
            //下划线转驼峰
            prop.setJavaField(lineToHump(columnName));
            log.info("{},{},{},{}", columnName, sqlDataType, propType, isPrimaryKey ? "主键" : "");
            propList.add(prop);
        }
        resultMap.put("tableName", tableName);
        resultMap.put("className", lineToHumpBig(tableName));
        resultMap.put("columns", propList);
        return resultMap;
    }

    /**
     * 下划线转驼峰
     */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 下划线转驼峰
     */
    public static String lineToHumpBig(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        char firstChar = sb.charAt(0);
        if (firstChar >= 97 && firstChar <= 122) {
            firstChar = (char) (firstChar - 32);
        }
        sb.setCharAt(0, firstChar);
        return sb.toString();
    }

    /**
     * 驼峰转下划线,效率比上面高
     */
    public static String humpToLine(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}
